package com.sk.weichat.mvp.presenter;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.sk.weichat.audio_x.VoicePlayer;
import com.sk.weichat.bean.Friend;
import com.sk.weichat.bean.message.ChatMessage;
import com.sk.weichat.bean.message.XmppMessage;
import com.sk.weichat.db.InternationalizationHelper;
import com.sk.weichat.db.dao.ChatMessageDao;
import com.sk.weichat.db.dao.FriendDao;
import com.sk.weichat.mvp.contract.ChatContract;
import com.sk.weichat.ui.MainActivity;
import com.sk.weichat.ui.base.CoreManager;
import com.sk.weichat.util.Constants;
import com.sk.weichat.util.PreferenceUtils;
import com.sk.weichat.util.ToastUtil;
import com.xuan.xuanhttplibrary.okhttp.HttpUtils;
import com.xuan.xuanhttplibrary.okhttp.callback.BaseCallback;
import com.xuan.xuanhttplibrary.okhttp.result.ObjectResult;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import fm.jiecao.jcvideoplayer_lib.JCMediaManager;
import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import pl.droidsonroids.gif.GifDrawable;

public class ChatPresenter implements ChatContract.Presenter {

    private final ChatContract.ChatView mChatView;
    private CoreManager mCoreManager;
    private RefreshBroadcastReceiver mRefreshBroadcastReceiver;
    private Friend mFriend;
    private String mLoginUserId;
    private List<ChatMessage> mChatMessages;// 存储聊天消息

    //记录对方正在输入的时间
    private AtomicLong lastInputTime = new AtomicLong(0);

    //检查正在输入时间间隔
    private static final int INPUT_INTERVAL_TIME = 1000;

    Disposable mDisposable;

    public void interval() {
        Observable.interval(1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable disposable) {
                        mDisposable = disposable;
                    }

                    @Override
                    public void onNext(@NonNull Long number) {
                        long current = System.currentTimeMillis();
                        long lastTime = lastInputTime.get();
                        // Log.e("lzs", "onNext:" + current + "   lastInputTime:" + lastInputTime.get());
                        if (current - lastInputTime.get() >= INPUT_INTERVAL_TIME && lastTime != 0) {
                            lastInputTime.set(0);
                            //设置成在线
                            mChatView.updateOnLineDescribe(InternationalizationHelper.getString("JX_OnLine"));
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


    public ChatPresenter(ChatContract.ChatView chatView, CoreManager coreManager) {
        this.mChatView = chatView;
        this.mCoreManager = coreManager;

    }

    public void bandData(Friend friend, String loginUserId, List<ChatMessage> chatMessages) {
        mFriend = friend;
        mLoginUserId = loginUserId;
        mChatMessages = chatMessages;
    }

    /**
     * 注册xmpp广播监听
     *
     * @param context 当前环境
     */
    public void registerXMPPReceiver(Context context) {
        mRefreshBroadcastReceiver = new RefreshBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.IsRead);
        intentFilter.addAction("Refresh");
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.TYPE_INPUT);
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.MSG_BACK);
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.NAME_CHANGE);
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.MULTI_LOGIN_READ_DELETE);
        intentFilter.addAction(Constants.CHAT_MESSAGE_DELETE_ACTION);
        intentFilter.addAction(Constants.SHOW_MORE_SELECT_MENU);
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.TYPE_DELALL);
        intentFilter.addAction(Constants.CHAT_HISTORY_EMPTY);
        intentFilter.addAction(com.sk.weichat.broadcast.OtherBroadcast.QC_FINISH);
        context.registerReceiver(mRefreshBroadcastReceiver, intentFilter);
    }

    /**
     * 注销xmpp广播监听
     *
     * @param context 当前环境
     */
    private void unRegisterXMPPReceiver(Context context) {
        context.unregisterReceiver(mRefreshBroadcastReceiver);
    }

    /*******************************************
     * 接收到广播后的后续操作
     ******************************************/
    public class RefreshBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.IsRead)) {
                // 收到已读的广播 单聊
                Bundle bundle = intent.getExtras();
                String packetId = bundle.getString("packetId");
                boolean isReadChange = bundle.getBoolean("isReadChange");
                for (int i = 1; i < mChatMessages.size(); i++) {
                    ChatMessage msg = mChatMessages.get(i);
                    if (msg.getPacketId().equals(packetId)) {
                        msg.setSendRead(true);// 更新为已读
                        if (isReadChange) {// 阅后即焚已读 且本地数据库已经修改
                            ChatMessage msgById = ChatMessageDao.getInstance().findMsgById(mLoginUserId, mFriend.getUserId(), packetId);
                            if (msgById != null) {
                                if (msg.getType() == XmppMessage.TYPE_VOICE) {
                                    if (!TextUtils.isEmpty(VoicePlayer.instance().getVoiceMsgId())
                                            && packetId.equals(VoicePlayer.instance().getVoiceMsgId())) {// 对方查看该语音时，我正在播放... 需要停止播放
                                        VoicePlayer.instance().stop();
                                    }
                                } else if (msg.getType() == XmppMessage.TYPE_VIDEO) {
                                    if (!TextUtils.isEmpty(JCMediaManager.CURRENT_PLAYING_URL)
                                            && msg.getContent().equals(JCMediaManager.CURRENT_PLAYING_URL)) {// 对方查看该视频时，我正在播放... 需要退出全屏、停止播放
                                        JCVideoPlayer.releaseAllVideos();
                                    }
                                }

                                msg.setType(msgById.getType());
                                msg.setContent(msgById.getContent());
                            }
                        }

                        mChatView.updateContent(false);
                        mChatView.changeOnLineState(true);
                        break;
                    }
                }
            } else if (action.equals("Refresh")) {
                Bundle bundle = intent.getExtras();
                String packetId = bundle.getString("packetId");

                // 这里表示正在聊天的时候，收到新消息，重新适配一下数据可以立即返回已读回执
                for (int i = 1; i < mChatMessages.size(); i++) {
                    ChatMessage msg = mChatMessages.get(i);
                    // 碰到packetId为空的就是刚刚加进来的消息
                    if (msg.getPacketId() == null) {
                        // 找到该消息，把已读标志设置为false，然后适配数据的时候就可以发现它，就可以回执已读了
                        msg.setSendRead(false); // 收到新消息，默认未读
                        msg.setFromUserId(mFriend.getUserId());
                        msg.setPacketId(packetId);
                        break;
                    }
                }
                mChatView.updateContent(false);
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.TYPE_INPUT)) { // 对方正在输入...
                String fromId = intent.getStringExtra("fromId");
                if (mFriend.getUserId().equals(fromId)) {
                    // 对方正在输入...
                    mChatView.updateOnLineDescribe(InternationalizationHelper.getString("JX_Entering"));
                    //Log.e("lzs", "对方正在输入：" + System.currentTimeMillis());
                    lastInputTime.set(System.currentTimeMillis());
                    if (null == mDisposable) {
                        //启动定时器
                        interval();
                    }
                }
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.MSG_BACK)) {
                String packetId = intent.getStringExtra("packetId");
                if (TextUtils.isEmpty(packetId)) {
                    return;
                }
                for (ChatMessage chatMessage : mChatMessages) {
                    if (packetId.equals(chatMessage.getPacketId())) {
                        if (chatMessage.getType() == XmppMessage.TYPE_VOICE
                                && !TextUtils.isEmpty(VoicePlayer.instance().getVoiceMsgId())
                                && packetId.equals(VoicePlayer.instance().getVoiceMsgId())) {// 语音 && 正在播放的msgId不为空 撤回的msgId==正在播放的msgId
                            // 停止播放语音
                            VoicePlayer.instance().stop();
                        }
                        ChatMessage chat = ChatMessageDao.getInstance().findMsgById(mLoginUserId, mFriend.getUserId(), packetId);
                        chatMessage.setType(chat.getType());
                        chatMessage.setContent(chat.getContent());
                        break;
                    }
                }
                mChatView.updateContent(true);
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.NAME_CHANGE)) {// 修改备注名
                mFriend = FriendDao.getInstance().getFriend(mLoginUserId, mFriend.getUserId());
                mChatView.changeChannelName(mFriend);
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.MULTI_LOGIN_READ_DELETE)) {// 兼容 多点登录 阅后即焚 其他端已读了该条消息
                String packet = intent.getStringExtra("MULTI_LOGIN_READ_DELETE_PACKET");
                if (!TextUtils.isEmpty(packet)) {

                    for (int i = 1; i < mChatMessages.size(); i++) {
                        if (mChatMessages.get(i).getPacketId().equals(packet)) {
                            mChatMessages.remove(i);
                            mChatView.updateContent(true);
                            break;
                        }
                    }
                }
            } else if (action.equals(Constants.CHAT_MESSAGE_DELETE_ACTION)) {

                if (mChatMessages == null || mChatMessages.size() == 1) {
                    return;
                }
                // 用户手动删除
                int position = intent.getIntExtra(Constants.CHAT_REMOVE_MESSAGE_POSITION, -1);
                if (position >= 1 && position < mChatMessages.size()) { // 合法的postion
                    ChatMessage message = mChatMessages.get(position);
                    deleteMessage(message.getPacketId());// 服务端也需要删除
                    if (ChatMessageDao.getInstance().deleteSingleChatMessage(mLoginUserId, mFriend.getUserId(), message)) {
                        mChatMessages.remove(position);
                        mChatView.updateContent(true);
                        mChatView.showToastMsg(InternationalizationHelper.getString("JXAlert_DeleteOK"));
                    } else {
                        mChatView.showToastMsg("删除失败");
                    }
                }

            } else if (action.equals(Constants.SHOW_MORE_SELECT_MENU)) {// 显示多选菜单
                int position = intent.getIntExtra(Constants.CHAT_SHOW_MESSAGE_POSITION, 0);
                mChatView.moreSelected(true, position);
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.TYPE_DELALL)) {
                // 被拉黑 || 删除  @see XChatManger 190
                // 好友被后台删除，xmpp 512,
                String toUserId = intent.getStringExtra("toUserId");
                // 只处理正在聊天对象是删除自己的人的情况，
                if (Objects.equals(mFriend.getUserId(), toUserId)) {
                    String content = intent.getStringExtra("content");
                    if (!TextUtils.isEmpty(content)) {
                        ToastUtil.showToast(context, content);
                    }
                    Intent mainIntent = new Intent(context, MainActivity.class);
                    context.startActivity(mainIntent);
                    mChatView.finishActivity();
                }
            } else if (action.equals(Constants.CHAT_HISTORY_EMPTY)) {// 清空聊天记录
                mChatMessages.clear();
                mChatView.updateContent(false);
            } else if (action.equals(com.sk.weichat.broadcast.OtherBroadcast.QC_FINISH)) {
                int mOperationCode = intent.getIntExtra("Operation_Code", 0);
                if (mOperationCode == 1) {// 更换聊天背景成功 更新当前页面
                    loadBackdrop(context);
                } else {// 快速创建群组成功 关闭当前页面
                    mChatView.finishActivity();
                }
            }
        }
    }

    /**
     * 更换聊天背景
     *
     * @param context 当前环境
     */
    public void loadBackdrop(Context context) {
        String mChatBgPath = PreferenceUtils.getString(context, Constants.SET_CHAT_BACKGROUND_PATH
                + mFriend.getUserId() + mLoginUserId, "reset");

        String mChatBg = PreferenceUtils.getString(context, Constants.SET_CHAT_BACKGROUND
                + mFriend.getUserId() + mLoginUserId, "reset");

        if (TextUtils.isEmpty(mChatBgPath)
                || mChatBg.equals("reset")) {// 未设置聊天背景或者还原了聊天背景
            mChatView.changeBackdrop(null);
            return;
        }

        File file = new File(mChatBgPath);
        if (file.exists()) {// 加载本地
            if (mChatBgPath.toLowerCase().endsWith("gif")) {
                try {
                    GifDrawable gifDrawable = new GifDrawable(file);
                    mChatView.changeBackdrop(gifDrawable);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                mChatView.changeBackdrop(file);
            }
        } else {// 加载网络
            mChatView.changeBackdrop(mChatBg);
        }
    }

    public void deleteMessage(String msgIdListStr) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("messageId", msgIdListStr);
        params.put("delete", "1");  // 1单方删除 2-双方删除
        params.put("type", "1");    // 1单聊记录 2-群聊记录

        HttpUtils.get().url(mCoreManager.getConfig().USER_DEL_CHATMESSAGE)
                .params(params)
                .build()
                .execute(new BaseCallback<Void>(Void.class) {

                    @Override
                    public void onResponse(ObjectResult<Void> result) {
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                    }
                });
    }

    public void onDestroy(Context context) {
        unRegisterXMPPReceiver(context);
        if (mDisposable != null) {
            mDisposable.dispose();
        }
    }

}
